package weaver.interfaces.autolink.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.engine.doc.service.impl.DocSecCategoryServiceImpl;
import okhttp3.*;
import org.apache.axis.encoding.Base64;
import weaver.docs.webservices.DocAttachment;
import weaver.docs.webservices.DocInfo;
import weaver.docs.webservices.DocServiceImpl;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.User;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author dusongsong
 * @date 2024年03月06日 15:03
 */
public class FeishuUtil {
    private static final String APP_ID = "cli_a55eab6508e8d00e";
    private static final String APP_SECRET = "2kP2fyxIPB5HzJAKfvjjqgF4o4CxoFkC";
    private static final String URL = "https://open.feishu.cn";
    private static final Map<String, String> API_MAP = new HashMap();

    static {
        //自建应用获取 app_access_token
        API_MAP.put("AppAccessToken", "/open-apis/auth/v3/app_access_token/internal");
        //获取 user_access_token
        API_MAP.put("AccessToken", "/open-apis/authen/v1/oidc/access_token");
        //刷新 user_access_token
        API_MAP.put("RefreshAccessToken", "/open-apis/authen/v1/oidc/refresh_access_token");
        //我的空间下的文件夹/获取文件夹下的清单
        API_MAP.put("Files", "/open-apis/drive/v1/files");
    }

    /**
     * 自建应用获取 app_access_token
     *
     * @return
     */
    private static String getAppAccessToken() {
        String app_access_token = "";
        JSONObject paramsJson = new JSONObject();
        paramsJson.put("app_id", APP_ID);
        paramsJson.put("app_secret", APP_SECRET);
        JSONObject resultJson = handleOKHttpPostRequest("AppAccessToken", paramsJson.toJSONString());
        String code = Util.null2String(resultJson.getString("code"));
        if ("success".equals(code)) {
            JSONObject retrunData = JSONObject.parseObject(resultJson.getString("data"));
            String msg = Util.null2String(retrunData.getString("msg"));
            if ("ok".equalsIgnoreCase(msg)) {
                app_access_token = Util.null2String(retrunData.getString("app_access_token"));
            }
        }
        return app_access_token;
    }

    /**
     * 获取 user_access_token
     *
     * @param app_access_token
     * @param authcode
     * @return
     */
    private static JSONObject getAccessToken(String app_access_token, String authcode) {
        JSONObject retrunJson = new JSONObject();
        JSONObject paramsJson = new JSONObject();
        paramsJson.put("grant_type", "authorization_code");
        paramsJson.put("code", authcode);
        String authorization = "Bearer " + app_access_token;
        JSONObject resultJson = handleOKHttpPostRequestAuth("AccessToken", paramsJson.toJSONString(), authorization);
        String code = Util.null2String(resultJson.getString("code"));
        //获取token成功
        if ("success".equals(code)) {
            JSONObject retrunData = JSONObject.parseObject(resultJson.getString("data"));
            String msg = Util.null2String(retrunData.getString("msg"));
            if ("success".equalsIgnoreCase(msg)) {
                JSONObject resultData = JSONObject.parseObject(retrunData.getString("data"));
                retrunJson.put("access_token", Util.null2String(resultData.getString("access_token")));
                retrunJson.put("refresh_token", Util.null2String(resultData.getString("refresh_token")));
            }
        }
        return retrunJson;
    }

    /**
     * 获取刷新token
     *
     * @param app_access_token
     * @param refresh_token
     * @return
     */
    private static JSONObject getRefreshToken(String app_access_token, String refresh_token) {
        JSONObject retrunJson = new JSONObject();
        JSONObject paramsJson = new JSONObject();
        paramsJson.put("grant_type", "refresh_token");
        paramsJson.put("refresh_token", refresh_token);
        String authorization = "Bearer " + app_access_token;
        JSONObject resultJson = handleOKHttpPostRequestAuth("RefreshAccessToken", paramsJson.toJSONString(), authorization);
        String code = Util.null2String(resultJson.getString("code"));
        // 刷新token成功
        if ("success".equals(code)) {
            JSONObject retrunData = JSONObject.parseObject(resultJson.getString("data"));
            String msg = Util.null2String(retrunData.getString("msg"));
            if ("success".equalsIgnoreCase(msg)) {
                JSONObject resultData = JSONObject.parseObject(retrunData.getString("data"));
                retrunJson.put("access_token", Util.null2String(resultData.getString("access_token")));
                retrunJson.put("refresh_token", Util.null2String(resultData.getString("refresh_token")));
            }
        }
        return retrunJson;
    }

    /**
     * 我的空间下的文件夹
     *
     * @param accessToken
     * @return
     */
    private static JSONArray getFoldersBySpace(String accessToken) {
        JSONArray foldersData = new JSONArray();
        String authorization = "Bearer " + accessToken;
        String apiUrl = URL + Util.null2String(API_MAP.get("Files"));
        apiUrl += "?direction=DESC&order_by=EditedTime";
        JSONObject resultJson = handleOKHttpGetRequestAuth(apiUrl, authorization);
        String code = Util.null2String(resultJson.getString("code"));
        if ("success".equals(code)) {
            JSONObject retrunData = JSONObject.parseObject(resultJson.getString("data"));
            String msg = Util.null2String(retrunData.getString("msg"));
            if ("success".equals(msg)) {
                JSONObject resultData = JSONObject.parseObject(retrunData.getString("data"));
                foldersData = JSONArray.parseArray(resultData.getString("files"));
            }
        }
        return foldersData;
    }

    /**
     * 获取文件夹下的清单
     *
     * @param accessToken
     * @param folder_token
     * @return
     */
    private static JSONArray getFilesByFolder(String accessToken, String folder_token) {
        JSONArray filesData = new JSONArray();
        String authorization = "Bearer " + accessToken;
        String apiUrl = URL + Util.null2String(API_MAP.get("Files"));
        apiUrl += "?direction=DESC&order_by=EditedTime&folder_token=" + folder_token;
        JSONObject resultJson = handleOKHttpGetRequestAuth(apiUrl, authorization);
        String code = Util.null2String(resultJson.getString("code"));
        if ("success".equals(code)) {
            JSONObject retrunData = JSONObject.parseObject(resultJson.getString("data"));
            String msg = Util.null2String(retrunData.getString("msg"));
            if ("success".equals(msg)) {
                JSONObject resultData = JSONObject.parseObject(retrunData.getString("data"));
                filesData = JSONArray.parseArray(resultData.getString("files"));
            }
        }
        return filesData;
    }

    /**
     * 下载文件
     *
     * @param accessToken
     * @param file_token
     * @return
     */
    private static int downloadFile(String accessToken, String file_token, String filename) {
        String authorization = "Bearer " + accessToken;
        int docid = -1;
        String apiUrl = URL + Util.null2String(API_MAP.get("Files"));
        apiUrl += "/" + file_token + "/download";
        try {
            OkHttpClient client = new OkHttpClient().newBuilder()
                    .connectTimeout(60, TimeUnit.SECONDS)
                    .readTimeout(60, TimeUnit.SECONDS)
                    .writeTimeout(60, TimeUnit.SECONDS)
                    .build();
            MediaType mediaType = MediaType.parse("text/plain");
            RequestBody body = RequestBody.create(mediaType, "");
            Request request = new Request.Builder()
                    .url(apiUrl)
                    .method("GET", body)
                    .addHeader("Authorization", authorization)
                    .build();
            Response response = client.newCall(request).execute();
            byte[] bytes = response.body().bytes();
            docid = createDocid(1, bytes, filename, 123);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return docid;
    }

    /**
     * 请求处理器-发送post请求带认证
     *
     * @param apiType
     * @param params
     * @param authorization
     * @return
     */
    private static JSONObject handleOKHttpPostRequestAuth(String apiType, String params, String authorization) {
        JSONObject resultJson = new JSONObject();
        String code = "failure";
        String message = "";
        String data = "";
        String apiUrl = URL + Util.null2String(API_MAP.get(apiType));
        try {
            OkHttpClient client = new OkHttpClient().newBuilder()
                    .connectTimeout(60, TimeUnit.SECONDS)
                    .readTimeout(60, TimeUnit.SECONDS)
                    .writeTimeout(60, TimeUnit.SECONDS)
                    .build();
            MediaType mediaType = MediaType.parse("application/json");
            RequestBody body = RequestBody.create(mediaType, params);
            Request request = new Request.Builder()
                    .url(apiUrl)
                    .method("POST", body)
                    .addHeader("Authorization", authorization)
                    .addHeader("Content-Type", "application/json")
                    .build();
            Response response = client.newCall(request).execute();
            String result = Util.null2String(response.body().string());
            if (!"".equals(result)) {
                data = result;
                code = "success";
            } else {
                message = "response result is null";
            }
        } catch (Exception e) {
            message = "response timeout";
            e.printStackTrace();
        }
        resultJson.put("code", code);
        resultJson.put("data", data);
        resultJson.put("message", message);
        return resultJson;
    }

    /**
     * 请求处理器-发送post请求
     *
     * @param apiType
     * @param params
     * @return
     */
    private static JSONObject handleOKHttpPostRequest(String apiType, String params) {
        JSONObject resultJson = new JSONObject();
        String code = "failure";
        String message = "";
        String data = "";
        String apiUrl = URL + Util.null2String(API_MAP.get(apiType));
        try {
            OkHttpClient client = new OkHttpClient().newBuilder()
                    .connectTimeout(60, TimeUnit.SECONDS)
                    .readTimeout(60, TimeUnit.SECONDS)
                    .writeTimeout(60, TimeUnit.SECONDS)
                    .build();
            MediaType mediaType = MediaType.parse("application/json");
            RequestBody body = RequestBody.create(mediaType, params);
            Request request = new Request.Builder()
                    .url(apiUrl)
                    .method("POST", body)
                    .addHeader("Content-Type", "application/json")
                    .build();
            Response response = client.newCall(request).execute();
            String result = Util.null2String(response.body().string());
            if (!"".equals(result)) {
                data = result;
                code = "success";
            } else {
                message = "response result is null";
            }
        } catch (Exception e) {
            message = "response timeout";
            e.printStackTrace();
        }
        resultJson.put("code", code);
        resultJson.put("data", data);
        resultJson.put("message", message);
        return resultJson;
    }

    /**
     * 请求处理器-发送GET请求带认证
     *
     * @param apiUrl
     * @param authorization
     * @return
     */
    private static JSONObject handleOKHttpGetRequestAuth(String apiUrl, String authorization) {
        JSONObject resultJson = new JSONObject();
        String code = "failure";
        String message = "";
        String data = "";
        try {
            OkHttpClient client = new OkHttpClient().newBuilder()
                    .connectTimeout(60, TimeUnit.SECONDS)
                    .readTimeout(60, TimeUnit.SECONDS)
                    .writeTimeout(60, TimeUnit.SECONDS)
                    .build();
            MediaType mediaType = MediaType.parse("text/plain");
            RequestBody body = RequestBody.create(mediaType, "");
            Request request = new Request.Builder()
                    .url(apiUrl)
                    .method("GET", body)
                    .addHeader("Authorization", authorization)
                    .build();
            Response response = client.newCall(request).execute();
            String result = Util.null2String(response.body().string());
            if (!"".equals(result)) {
                data = result;
                code = "success";
            } else {
                message = "response result is null";
            }
        } catch (Exception e) {
            message = "response timeout";
            e.printStackTrace();
        }
        resultJson.put("code", code);
        resultJson.put("data", data);
        resultJson.put("message", message);
        return resultJson;
    }

    /**
     * 创建文件
     *
     * @param userid
     * @param content
     * @param rawFileName
     * @param seccategory
     * @return
     */
    private static int createDocid(int userid, byte[] content, String rawFileName, int seccategory) {
        BaseBean log = new BaseBean();
        // 上传附件，创建html文档
        int docid = -1;
        DocServiceImpl docserviceimpl = new DocServiceImpl();
        DocAttachment[] docattachment = new DocAttachment[1];
        String docsubject = ""; //文档标题
        String keyword = ""; //文档内容
        String filetype = "";
        String filename = "";
        if (rawFileName.lastIndexOf(".") > -1) {
            filetype = rawFileName.substring(rawFileName.lastIndexOf(".") + 1);
            filename = rawFileName.substring(0, rawFileName.lastIndexOf("."));
        }
        try {
            DocAttachment da = new DocAttachment();
            da.setFilename(filename + "." + filetype);//附件标题
            da.setFilecontent(Base64.encode(content)); //附件内容
            da.setFiletype(filetype); //imagefiletype
            da.setImagefilename(filename + "." + filetype);// 附件标题
            da.setIszip(1);//是否压缩
            da.setIsAesEncrype(0);//是否加密
            da.setAesCode("0");
            da.setIsextfile("1"); //附件是否是office类型
            if (filetype.equalsIgnoreCase("doc")) {
                da.setDocfiletype("3");
            } else if (filetype.equalsIgnoreCase("xls")) {
                da.setDocfiletype("4");
            } else if (filetype.equalsIgnoreCase("ppt")) {
                da.setDocfiletype("5");
            } else if (filetype.equalsIgnoreCase("wps")) {
                da.setDocfiletype("6");
            } else if (filetype.equalsIgnoreCase("docx")) {
                da.setDocfiletype("7");
            } else if (filetype.equalsIgnoreCase("xlsx")) {
                da.setDocfiletype("8");
            } else if (filetype.equalsIgnoreCase("pptx")) {
                da.setDocfiletype("9");
            } else {
                da.setDocfiletype("2");
            }
            docattachment[0] = da;
            docsubject = filename;
            keyword = filename;
            DocInfo doc = new DocInfo();//创建文档
            doc.setSeccategory(seccategory);//子目录id
            doc.setDocSubject(docsubject);//标题
            doc.setDoccontent("");//文档内容
            doc.setKeyword(keyword);
            doc.setAttachments(docattachment);
            if (!"".equals(userid)) {
                User user = new User(userid);
                docid = docserviceimpl.createDocByUser(doc, user);
            }


        } catch (Exception e) {
            e.printStackTrace();
            log.writeLog("e:" + e);
        }
        return docid;
    }

    /**
     * 新建目录/下级目录
     *
     * @param categoryname     目录名称  必填/不能为空
     * @param coder            目录编码  非必填
     * @param extendParentAttr 是否继承上级目录设置  非必填  0=false  1=true
     * @param noRepeatedName
     * @param parentid
     * @param secorder
     * @param subcompanyid
     * @return
     */
    public Boolean createCategory(String categoryname, String coder, String extendParentAttr, String noRepeatedName, String parentid, String secorder, String subcompanyid) {
        Boolean api_status = false;
        Map<String, Object> result = new HashMap<>();
        Map<String, Object> param = new HashMap<>();
        param.put("categoryname", categoryname);
        param.put("coder", coder);
        param.put("extendParentAttr", extendParentAttr);
        param.put("noRepeatedName", noRepeatedName);
        param.put("parentid", parentid);
        param.put("secorder", secorder);
        param.put("subcompanyid", Util.getIntValue(subcompanyid, 0) + "");
        try {
            DocSecCategoryServiceImpl docSecCategoryService = new DocSecCategoryServiceImpl();
            result = docSecCategoryService.addDocMainCategory(param);
            api_status = (Boolean) result.get("api_status");
        } catch (Exception e) {
            api_status = false;
        }
        return api_status;
    }

}
